<?php
defined( 'BASEPATH' ) OR exit( 'No direct script access allowed' );

/**
 *  function_helper
 */

if ( !function_exists( 'br2nl' ) ) {
    /**
     * @param $text
     * @return mixed
     */
    function br2nl ( $text )
    {
        return preg_replace( '/<br\\s*?\/??>/i', '', $text );
    }
}
/**
 * replace all linebreaks to <br />
 * windows = \r\n 
 * unix = \n 
 * mac = \r 
 */
if ( !function_exists( 'func_nl2br' ) ) {
    function func_nl2br($string) { 
        $linebreaksArr =  array(
            '\r\n', 
            '\r', 
            '\n',
            // chr(30), 
            // chr(155), 
            PHP_EOL,
        );
        return str_replace( $linebreaksArr, "<br />", $string ); 
    } 
}
/**
 * Returns string with newline formatting converted into HTML paragraphs.
 *
 * @param string $string String to be formatted.
 * @param boolean $line_breaks When true, single-line line-breaks will be converted to HTML break tags.
 * @param boolean $xml When true, an XML self-closing tag will be applied to break tags (<br />).
 * @return string
 */
function func_nl2p($string, $line_breaks = true, $xml = true)
{
    // Remove existing HTML formatting to avoid double-wrapping things
    $string = str_replace(array('<p>', '</p>', '<br>', '<br />'), '', $string);
    // It is conceivable that people might still want single line-breaks
    // without breaking into a new paragraph.
    if ($line_breaks == true){
        return '<p>'.preg_replace(array("/([\n]{2,})/i", "/([^>])\n([^<])/i"), array("</p>\n<p>", '<br'.($xml == true ? ' /' : '').'>'), trim($string)).'</p>';

      } else {
        return '<p>'.preg_replace("/([\n]{1,})/i", "</p>\n<p>", trim($string)).'</p>';
    } 
}


/**
 * 截取中英混排字符串
 *
 * @param        $string
 * @param        $length
 * @param string $dot
 * @param string $charset
 * @return string
 */
function utf8_substr ( $string, $length, $dot = '..', $charset = 'utf-8' )
{
    if ( function_exists( 'mb_substr' ) ) {
        $sLength = mb_strlen( $string );
    } else {
        $sLength = strlen( $string );
    }

    if ( $sLength <= $length ) {
        return $string;
    }
    if ( function_exists( 'mb_substr' ) ) {
        return mb_substr( $string, 0, $length, $charset ) . $dot;
    }
    $strcut = '';
    if ( strtolower( $charset ) == 'utf-8' ) {
        $n = $tn = $noc = 0;
        while ( $n < $sLength ) {
            $t = ord( $string[ $n ] );
            if ( $t == 9 || $t == 10 || ( 32 <= $t && $t <= 126 ) ) {
                $tn = 1;
                $n ++;
                $noc ++;
            } elseif ( 194 <= $t && $t <= 223 ) {
                $tn = 2;
                $n += 2;
                $noc += 1;
            } elseif ( 224 <= $t && $t < 239 ) {
                $tn = 3;
                $n += 3;
                $noc += 1;
            } elseif ( 240 <= $t && $t <= 247 ) {
                $tn = 4;
                $n += 4;
                $noc += 1;
            } elseif ( 248 <= $t && $t <= 251 ) {
                $tn = 5;
                $n += 5;
                $noc += 1;
            } elseif ( $t == 252 || $t == 253 ) {
                $tn = 6;
                $n += 6;
                $noc += 1;
            } else {
                $n ++;
            }
            if ( $noc >= $length ) {
                break;
            }
        }
        if ( $noc > $length ) {
            $n -= $tn;
        }
        $strcut = substr( $string, 0, $n );
    } else {
        for ( $i = 0; $i < $length; $i ++ ) {
            $strcut .= ord( $string[ $i ] ) > 127 ? $string[ $i ] . $string[ ++ $i ] : $string[ $i ];
        }
    }

    return $strcut . $dot;
}

/**
 * 清除HTML标记
 *
 * @param    string $str
 * @return  string
 */
function cleanhtml ( $str )
{
    $str = strip_tags( $str );
    $str = htmlspecialchars( $str );
    $str = preg_replace( "/\s+/", " ", $str ); //过滤多余回车
    $str = preg_replace( "/ /", "", $str );
    $str = preg_replace( "/&nbsp;/", "", $str );
    $str = preg_replace( "/　/", "", $str );
    $str = preg_replace( "/\r\n/", "", $str );
    $str = str_replace( chr( 13 ), "", $str );
    $str = str_replace( chr( 10 ), "", $str );
    $str = str_replace( chr( 9 ), "", $str );

    return $str;
}

/**
 * @return mixed
 */
function check_auth ()
{
    $url = 'http://www.kaixincms.com/authorize/check_auth/' . get_domain();
    if ( function_exists( 'file_get_contents' ) ) {
        $data = file_get_contents( $url );
    } else {
        $ch = curl_init();
        $timeout = 5;
        curl_setopt( $ch, CURLOPT_URL, $url );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
        $data = curl_exec( $ch );
        curl_close( $ch );
    }
    $data = json_decode( $data );

    return $data->product;
}

/**
 * @param string $url
 * @return string
 */
function get_domain ( $url = '' )
{
    $host = $url ? $url : @$_SERVER[ HTTP_HOST ];
    $host = strtolower( $host );
    if ( strpos( $host, '/' ) !== FALSE ) {
        $parse = @parse_url( $host );
        $host = $parse['host'];
    }
    $topleveldomaindb = array ( 'com', 'edu', 'gov', 'int', 'mil', 'net', 'org', 'biz', 'info', 'pro', 'name', 'museum', 'coop', 'aero', 'xxx', 'idv', 'mobi', 'cc', 'me', 'cn', 'tv', 'in', 'hk', 'de', 'us', 'tw' );
    $str = '';
    foreach ( $topleveldomaindb as $v ) {
        $str .= ( $str ? '|' : '' ) . $v;
    }
    $matchstr = "[^\.]+\.(?:(" . $str . ")|\w{2}|((" . $str . ")\.\w{2}))$";
    if ( preg_match( "/" . $matchstr . "/ies", $host, $matchs ) ) {
        $domain = $matchs['0'];
    } else {
        $domain = $host;
    }

    return $domain;
}

//无编辑器的过滤
/*function filter_check ($data)
{
    $pattern="/<pre>(.*?)<\/pre>/si";
    preg_match_all ($pattern, $data, $matches);
    foreach( $matches[1] as $val ){
        @$replace[] = htmlspecialchars($val);
    }
    $data = str_replace($matches[1], @$replace, $data);
    if(!$matches[1]){
        $data = nl2br($data);
    }
    $data = str_replace('</p><br />','</p>',$data);
    return $data = strip_tags($data,"<p> <font> <img> <b> <strong> <br> <pre> <br /> <span>");
}*/
//无编辑器的过滤
function filter_check ( $str )
{

    $pattern = "/<pre[^>]*>(.*?)<\/pre>/si";
    preg_match_all( $pattern, $str, $matches );
    $str = htmlspecialchars_decode( $str );
    $str = stripslashes( $str );
    if ( $matches[1] ) {
        foreach ( $matches[1] as $v ) {
            $replace[] = addslashes( htmlspecialchars( trim( $v ) ) );
        }
        $str = str_replace( $matches[1], $replace, $str );
    } else {
        $str = strip_tags( $str, "<img> <pre> <a> <font> <span> <em>" );
    }
    $str = nl2br( $str );

    return $str;
}

/**
 * @param $str
 * @return mixed|string
 */
function filter_code ( $str )
{
    $str = htmlspecialchars_decode( $str );
    $pattern = "/<pre[^>]*>(.*?)<\/pre>/si";
    preg_match_all( $pattern, $str, $matches );
    if ( $matches[1] ) {
        foreach ( $matches[1] as $v ) {
            $replace = trim( htmlentities( $v ) );
            $str = str_replace( $v, $replace, $str );
        }
        $str = strip_tags( $str, "<img> <pre> <a> <font> <span> <em> <p> <b>" );
    } else {
        $str = strip_tags( $str, "<img> <pre> <a> <font> <span> <em> <p> <b>" );
        $str = trim( nl2br( $str ) );
    }

    return $str;
}

/**
 * 发送邮件
 *
 * @param $to
 * @param $subject
 * @param $message
 * @return bool
 */
function send_mail ( $to, $subject, $message )
{
    $ci = &get_instance();
    $config['protocol'] = $ci->config->item( 'protocol' );
    $config['smtp_host'] = $ci->config->item( 'smtp_host' );
    $config['smtp_user'] = $ci->config->item( 'smtp_user' );
    $config['smtp_pass'] = $ci->config->item( 'smtp_pass' );
    $config['smtp_port'] = $ci->config->item( 'smtp_port' );
    $config['charset'] = 'utf-8';
    $config['wordwrap'] = TRUE;
    $config['mailtype'] = 'html';

    $ci->load->library( 'email', $config );
    $ci->email->from( $config['smtp_user'], '' );
    $ci->email->to( $to );
    $ci->email->subject( $subject . '-' . $ci->config->item( 'site_name' ) );
    $ci->email->message( $message );
    if ( $ci->email->send() ) {
        return TRUE;
    } else {
        return FALSE;
    }
}

/**
 * @param        $str
 * @param string $type
 * @param bool   $popup
 * @return mixed
 */
function auto_link_pic ( $str, $type = 'both', $popup = FALSE )
{
    if ( $type != 'email' ) {
        if ( preg_match_all( "#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches ) ) {
            $pop = ( $popup == TRUE ) ? " target=\"_blank\" " : "";

            for ( $i = 0; $i < count( $matches['0'] ); $i ++ ) {
                $period = '';
                if ( preg_match( "|\.$|", $matches['6'][ $i ] ) ) {
                    $period = '.';
                    $matches['6'][ $i ] = substr( $matches['6'][ $i ], 0, - 1 );
                }
                $img_ext = array ( 'jpg', 'png', 'gif', 'jpeg' );
                //$url_string = $matches['0'][$i];
                $file_ext = pathinfo( $matches['0'][ $i ], PATHINFO_EXTENSION );
                //$file_ext = strtolower(end(explode(".", $matches['0'][$i])));
                //var_dump($file_ext);
                if ( in_array( $file_ext, $img_ext ) ) {
                    $str = str_replace( $matches['0'][ $i ],
                        $matches['1'][ $i ] . '<img src="http' .
                        $matches['4'][ $i ] . '://' .
                        $matches['5'][ $i ] .
                        $matches['6'][ $i ] . '" alt="">' .
                        $period, $str );
                } else {
                    $str = str_replace( $matches['0'][ $i ],
                        $matches['1'][ $i ] . '<a href="http' .
                        $matches['4'][ $i ] . '://' .
                        $matches['5'][ $i ] .
                        $matches['6'][ $i ] . '"' . $pop . '>http' .
                        $matches['4'][ $i ] . '://' .
                        $matches['5'][ $i ] .
                        $matches['6'][ $i ] . '</a>' .
                        $period, $str );
                }
            }
        }
    }

    if ( $type != 'url' ) {
        if ( preg_match_all( "/([a-zA-Z0-9_\.\-\+]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches ) ) {
            for ( $i = 0; $i < count( $matches['0'] ); $i ++ ) {
                $period = '';
                if ( preg_match( "|\.$|", $matches['3'][ $i ] ) ) {
                    $period = '.';
                    $matches['3'][ $i ] = substr( $matches['3'][ $i ], 0, - 1 );
                }

                $str = str_replace( $matches['0'][ $i ], safe_mailto( $matches['1'][ $i ] . '@' . $matches['2'][ $i ] . '.' . $matches['3'][ $i ] ) . $period, $str );
            }
        }
    }

    return $str;
}


/**
 * @param $input_str
 * @return mixed
 */
function xss_clean ( $input_str )
{
    $return_str = str_replace( array ( '<', '>', "'", '"', ')', '(' ), array ( '&lt;', '&gt;', '&apos;', '&#x22;', '&#x29;', '&#x28;' ), $input_str );
    $return_str = str_ireplace( '%3Cscript', '', $return_str );

    return $return_str;
}

/**
 * @param $str
 * @return string
 */
function xss_clean3 ( $str )
{

    if ( isset( $str ) ) {
        $str = trim( $str );  //清理空格
        $str = strip_tags( $str );   //过滤html标签
        $str = htmlspecialchars( $str );   //将字符内容转化为html实体
        $str = addslashes( $str );

        return $str;
    }


}

/*
 * XSS filter 
 *
 * This was built from numerous sources
 * (thanks all, sorry I didn't track to credit you)
 */
/**
 * @param $data
 * @return mixed|string
 */
function xss_clean1 ( $data )
{
    // Fix &entity\n;
    $data = str_replace( array ( '&amp;', '&lt;', '&gt;' ), array ( '&amp;amp;', '&amp;lt;', '&amp;gt;' ), $data );
    $data = preg_replace( '/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data );
    $data = preg_replace( '/(&#x*[0-9A-F]+);*/iu', '$1;', $data );
    $data = html_entity_decode( $data, ENT_COMPAT, 'UTF-8' );

    // Remove any attribute starting with "on" or xmlns
    $data = preg_replace( '#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data );

    // Remove javascript: and vbscript: protocols
    $data = preg_replace( '#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data );
    $data = preg_replace( '#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data );
    $data = preg_replace( '#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data );

    // Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
    $data = preg_replace( '#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data );
    $data = preg_replace( '#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data );
    $data = preg_replace( '#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data );

    // Remove namespaced elements (we do not need them)
    $data = preg_replace( '#</*\w+:\w[^>]*+>#i', '', $data );

    do {
        // Remove really unwanted tags
        $old_data = $data;
        $data = preg_replace( '#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data );
    } while ( $old_data !== $data );

    // we are done...
    return $data;
}

/**
 * @param $length
 * @return string
 */
function randkey ( $length )
{
    $pattern = '1234567890abcdefghijklmnopqrstuvwxyz$#&^@!';
    $key = '';
    for ( $i = 0; $i < $length; $i ++ ) {
        $key .= $pattern{mt_rand( 0, 35 )};    //生成php随机数
    }

    return $key;
}

/**
 * @param $url
 * @return mixed|string
 */
function get_url_content ( $url )
{
    if ( function_exists( 'file_get_contents' ) ) {
        return file_get_contents( $url );
    } elseif ( function_exists( 'curl_init' ) ) {
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $url );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
        curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );

        return curl_exec( $ch );
    }
}

/**
 * @param int $length
 * @return string
 */
function get_salt ( $length = - 6 )
{
    return substr( uniqid( rand() ), $length );
}


/**
 * @param $password
 * @param $salt
 * @return string
 */
function password_dohash ( $password, $salt )
{
    $salt = $salt ? $salt : get_salt();

    return md5( md5( $password ) . $salt );
}

/**
 * @param string $message
 * @param string $url
 * @param int    $status
 * @param string $heading
 * @param int    $time
 */
function show_message ( $message = '', $url = '', $status = 2, $heading = '提示信息', $time = 1800 )
{
    //var_dump($message);
    include APPPATH . 'views/show_message.php';
    exit;
}

/**
 * 获得用户本地真实IP
 *
 * @return mixed
 */
function get_onlineip ()
{
    $ip_json = @file_get_contents( "http://ip.taobao.com/service/getIpInfo.php?ip=myip" );
    $ip_arr = json_decode( stripslashes( $ip_json ), 1 );
    if ( $ip_arr['code'] == 0 ) {
        return $ip_arr['data']['ip'];
    }

}

/**补全代码
 *
 * @param $html
 * @return string
 */
function closetags ( $html )
{
    // 不需要补全的标签
    $arr_single_tags = array ( 'meta', 'img', 'br', 'link', 'area' );
    // 匹配开始标签
    preg_match_all( '#<([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result );
    $openedtags = $result[1];
    // 匹配关闭标签
    preg_match_all( '#</([a-z]+)>#iU', $html, $result );
    $closedtags = $result[1];
    // 计算关闭开启标签数量，如果相同就返回html数据
    $len_opened = count( $openedtags );
    if ( count( $closedtags ) == $len_opened ) {
        return $html;
    }
    // 把排序数组，将最后一个开启的标签放在最前面
    $openedtags = array_reverse( $openedtags );
    // 遍历开启标签数组
    for ( $i = 0; $i < $len_opened; $i ++ ) {
        // 如果需要补全的标签
        if ( !in_array( $openedtags[ $i ], $arr_single_tags ) ) {
            // 如果这个标签不在关闭的标签中
            if ( !in_array( $openedtags[ $i ], $closedtags ) ) {
                // 直接补全闭合标签
                $html .= '</' . $openedtags[ $i ] . '>';
            } else {
                unset( $closedtags[ array_search( $openedtags[ $i ], $closedtags ) ] );
            }
        }
    }

    return $html;
}

/**
 * @param $str
 * @return mixed
 */
function strip_url_tags ( $str )
{
    $str = preg_replace( "/<a[^>]*href=[^>]*>|<\/[^a]*a[^>]*>/i", "\\2", $str );

    return $str;
}

/**
 * @param $content
 * @return mixed
 */
function decode_format ( $content )
{
    $STB = &get_instance();
    $STB->load->helper( 'security' );
    $content = strip_url_tags( strip_image_tags( $content ) );

    return $content;
}

/**
 * @param     $data
 * @param int $parentId
 * @return array
 */
function get_tree_array ( &$data, $parentId = 0 )
{
    $category = array ();
    foreach ( $data as $key => $value ) {
        if ( $value['pid'] == $parentId ) {
            unset( $data[ $key ] );
            $value['child'] = category( $data, $value['id'] );
            $category[] = $value;
        }
    }

    return $category;
}

/**
 * @param     $data
 * @param int $parentId
 * @return string
 */
function get_tree ( &$data, $parentId = 0 )
{
    global $str;
    $str .= '<ul>';
    foreach ( $data as $key => $value ) {
        if ( $value['pid'] == $parentId ) {
            unset( $data[ $key ] );
            $str .= "<li>|--<a href='/'>" . $value['name'] . '</a></li>';
            get_tree( $data, $value['id'] );
        }
    }
    $str .= '</ul>';

    return $str;
}

/**
 * createRouteUrl
 *
 * @param string $type
 * @param string $num
 * @param string $any
 * @return mixed
 */
function createRouteUrl ( $type = '', $num = '', $any = '' )
{
    $CI_INSTANCE = &get_instance();

    return $CI_INSTANCE->router->createRouteUrl( $type, $num, $any );
}

/**
 * 将时间格式化成友好时间格式
 * 比如：刚刚，30秒前，5分钟前，8小时前:
 *
 * @param $from
 * @return bool|string
 */
function  friendly_date ( $from )
{
    static $now = NULL;
    $now == NULL && $now = time();
    !is_numeric( $from ) && $from = strtotime( $from );
    $seconds = $now - $from;
    $minutes = floor( $seconds / 60 );
    $hours = floor( $seconds / 3600 );
    $day = round( ( strtotime( date( 'Y-m-d', $now ) ) - strtotime( date( 'Y-m-d', $from ) ) ) / 86400 );
    if ( $seconds == 0 ) {
        return '刚刚';
    }
    if ( ( $seconds >= 0 ) && ( $seconds <= 60 ) ) {
        return "{$seconds}秒前";
    }
    if ( ( $minutes >= 0 ) && ( $minutes <= 60 ) ) {
        return "{$minutes}分钟前";
    }
    if ( ( $hours >= 0 ) && ( $hours <= 24 ) ) {
        return "{$hours}小时前";
    }
    if ( ( date( 'Y' ) - date( 'Y', $from ) ) > 0 ) {
        return date( 'Y-m-d', $from );
    }

    switch ( $day ) {
        case 0:
            return date( '今天H:i', $from );
            break;

        case 1:
            return date( '昨天H:i', $from );
            break;

        default:
            //$day += 1;
            return "{$day} 天前";
            break;
    }
}

/**
 * @param $str
 * @return int
 */
function str_len ( $str )
{
    $length = strlen( preg_replace( '/[\x00-\x7F]/', '', $str ) );

    if ( $length ) {
        return strlen( $str ) - $length + intval( $length / 3 ) * 2;
    } else {
        return strlen( $str );
    }
}

/**
 * array_column
 */
if ( !function_exists( 'array_column' ) ) {
    /**
     * @param      $input
     * @param      $columnKey
     * @param null $indexKey
     * @return array
     */
    function array_column ( $input, $columnKey, $indexKey = NULL )
    {
        $columnKeyIsNumber = ( is_numeric( $columnKey ) ) ? TRUE : FALSE;
        $indexKeyIsNull = ( is_null( $indexKey ) ) ? TRUE : FALSE;
        $indexKeyIsNumber = ( is_numeric( $indexKey ) ) ? TRUE : FALSE;
        $result = array ();
        foreach ( (array)$input as $key => $row ) {
            if ( $columnKeyIsNumber ) {
                $tmp = array_slice( $row, $columnKey, 1 );
                $tmp = ( is_array( $tmp ) && !empty( $tmp ) ) ? current( $tmp ) : NULL;
            } else {
                $tmp = isset( $row[ $columnKey ] ) ? $row[ $columnKey ] : NULL;
            }
            if ( !$indexKeyIsNull ) {
                if ( $indexKeyIsNumber ) {
                    $key = array_slice( $row, $indexKey, 1 );
                    $key = ( is_array( $key ) && !empty( $key ) ) ? current( $key ) : NULL;
                    $key = is_null( $key ) ? 0 : $key;
                } else {
                    $key = isset( $row[ $indexKey ] ) ? $row[ $indexKey ] : 0;
                }
            }
            $result[ $key ] = $tmp;
        }

        return $result;
    }
}

/**
 * @param $time
 * @return bool
 */
function is_today ( $time )
{
    $date = date( 'Y-m-d', $time );
    $today = date( 'Y-m-d' );
    if ( $date == $today ) {
        return TRUE;
    } else {
        return FALSE;
    }

}


if ( !function_exists( 'br2nl' ) ) {
    /**
     * @param $text
     * @return mixed
     */
    function br2nl ( $text )
    {
        return preg_replace( '/<br\\s*?\/??>/i', '', $text );
    }
}


/**
 * remove_xss
 */

if ( !function_exists( ' remove_xss' ) ) {
    /**
     * @param $val
     * @return mixed
     */
    function remove_xss ( $val )
    {
        // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
        // this prevents some character re-spacing such as <java\0script>
        // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
        $val = preg_replace( '/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val );

        // straight replacements, the user should never need these since they're normal characters
        // this prevents like <IMG SRC=@avascript:alert('XSS')>
        $search = 'abcdefghijklmnopqrstuvwxyz';
        $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $search .= '1234567890!@#$%^&*()';
        $search .= '~`";:?+/={}[]-_|\'\\';
        for ( $i = 0; $i < strlen( $search ); $i ++ ) {
            // ;? matches the ;, which is optional
            // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars

            // @ @ search for the hex values
            $val = preg_replace( '/(&#[xX]0{0,8}' . dechex( ord( $search[ $i ] ) ) . ';?)/i', $search[ $i ], $val ); // with a ;
            // @ @ 0{0,7} matches '0' zero to seven times
            $val = preg_replace( '/(�{0,8}' . ord( $search[ $i ] ) . ';?)/', $search[ $i ], $val ); // with a ;
        }

        // now the only remaining whitespace attacks are \t, \n, and \r
        $ra1 = array ( 'javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base' );
        $ra2 = array ( 'onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload' );
        $ra = array_merge( $ra1, $ra2 );

        $found = TRUE; // keep replacing as long as the previous round replaced something
        while ( $found == TRUE ) {
            $val_before = $val;
            for ( $i = 0; $i < sizeof( $ra ); $i ++ ) {
                $pattern = '/';
                for ( $j = 0; $j < strlen( $ra[ $i ] ); $j ++ ) {
                    if ( $j > 0 ) {
                        $pattern .= '(';
                        $pattern .= '(&#[xX]0{0,8}([9ab]);)';
                        $pattern .= '|';
                        $pattern .= '|(�{0,8}([9|10|13]);)';
                        $pattern .= ')*';
                    }
                    $pattern .= $ra[ $i ][ $j ];
                }
                $pattern .= '/i';
                $replacement = substr( $ra[ $i ], 0, 2 ) . '<x>' . substr( $ra[ $i ], 2 ); // add in <> to nerf the tag
                $val = preg_replace( $pattern, $replacement, $val ); // filter out the hex tags
                if ( $val_before == $val ) {
                    // no replacements were made, so exit the loop
                    $found = FALSE;
                }
            }
        }

        return $val;
    }   //END function

    // ------------------------------------------------------------------------

    if ( defined( 'FUNCTION_DEBUG' ) || !function_exists( 'GetOnlineIp' ) ) {
        /**
         * 获取访问者IP
         *
         * @return string IP地址
         */
        function GetOnlineIp ()
        {
            $onlineip = '';
            if ( $_SERVER['HTTP_X_REAL_IP'] ) {
                $onlineip = $_SERVER['HTTP_X_REAL_IP'];
            } elseif ( $_SERVER['HTTP_X_FORWARDED_FOR'] ) {
                $arr = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
                $pos = array_search( 'unknown', $arr );
                if ( FALSE !== $pos ) {
                    unset( $arr[ $pos ] );
                }
                $onlineip = trim( $arr[0] );
            } elseif ( getenv( 'HTTP_CLIENT_IP' ) && strcasecmp( getenv( 'HTTP_CLIENT_IP' ), 'unknown' ) ) {
                $onlineip = getenv( 'HTTP_CLIENT_IP' );
            } elseif ( getenv( 'HTTP_X_FORWARDED_FOR' ) && strcasecmp( getenv( 'HTTP_X_FORWARDED_FOR' ), 'unknown' ) ) {
                $onlineip = getenv( 'HTTP_X_FORWARDED_FOR' );
            } elseif ( getenv( 'REMOTE_ADDR' ) && strcasecmp( getenv( 'REMOTE_ADDR' ), 'unknown' ) ) {
                $onlineip = getenv( 'REMOTE_ADDR' );
            } elseif ( $_SERVER['REMOTE_ADDR'] && strcasecmp( $_SERVER['REMOTE_ADDR'], 'unknown' ) ) {
                $onlineip = $_SERVER['REMOTE_ADDR'];
            }

            return $onlineip;
        }
    }
    // --------------------------------------------------------------------

    // 居民身份证号码(公民身份号码)是特征组合码，由十七位数字本体码和一位数字校验码组成。
    // 从1999年10月1日起，全国实行公民身份证号码制度，居民身份证编号由原15位升至18位。

    // 1．号码的结构 
    // 　　公民身份号码是特征组合码，由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为：六位数字地址码，八位数字出生日期码，三位数字顺序码和一位数字校验码。 
    // 2．地址码 
    // 　　表示编码对象常住户口所在县（市、旗、区）的行政区划代码，按GB/T2260的规定执行。 
    // 3．出生日期码 
    // 　　表示编码对象出生的年、月、日，按GB/T7408的规定执行，年、月、日代码之间不用分隔符。 
    // 4．顺序码 
    // 　　表示在同一地址码所标识的区域范围内，对同年、同月、同日出生的人编定的顺序号，顺序码的奇数分配给男性，偶数分配给女性。 
    // 5．校验码
    // 　　根据前面十七位数字码，按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。

    // 校验码规则：
    // 作为尾号的校验码，是由号码编制单位按统一的公式计算出来的，如果某人的尾号是0-9，都不会出现X，但如果尾号是10，那么就得用X来代替。
    // Ⅹ是罗马数字的10，用X来代替10，可以保证公民的身份证符合国家标准。

    if ( defined( 'FUNCTION_DEBUG' ) || !function_exists( 'GetIdCardLastVerifyNumber' ) ) {
        /**
         * 获取身份证最后一位效验码
         *
         * @param $base string 18位身份证号码
         * @return string 最后一位效验码
         */
        function GetIdCardLastVerifyNumber ( $idCardNum = '' )
        {
            if ( strlen( $idCardNum ) == 18 ) {
                $idCardNum = substr( $idCardNum, 0, 17 );
            }
            if ( strlen( $idCardNum ) != 17 ) {
                return FALSE;
            }
            $factorNumberArr = array ( 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ); //加权因子
            $verifyNumberArr = array ( '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' ); //校验码对应值
            $checkSum = 0;
            for ( $i = 0; $i < strlen( $idCardNum ); $i ++ ) {
                $checkSum .= substr( $idCardNum, $i, 1 ) * $factorNumberArr[ $i ];
            }
            $mod = $checkSum % 11;
            $verifyNumber = $verifyNumberArr[ $mod ];

            return $verifyNumber;
        }
    }

    if ( defined( 'FUNCTION_DEBUG' ) || !function_exists( 'GetIdCard15To18' ) ) {
        /**
         * 将15位身份证号码转为18位
         *
         * @param  $srcIdCardNum string 18位身份证号码
         * @return string 15位身份证号码
         */
        function GetIdCard15To18 ( $srcIdCardNum = 0 )
        {
            if ( strlen( $srcIdCardNum ) != 15 ) {
                return FALSE;
            } else {
                // 如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码
                if ( array_search( substr( $srcIdCardNum, 12, 3 ), array ( '996', '997', '998', '999' ) ) !== FALSE ) {
                    $srcIdCardNum = substr( $srcIdCardNum, 0, 6 ) . '18' . substr( $srcIdCardNum, 6, 9 );
                } else {
                    $srcIdCardNum = substr( $srcIdCardNum, 0, 6 ) . '19' . substr( $srcIdCardNum, 6, 9 );
                }
            }

            return $srcIdCardNum . GetIdCardLastVerifyNumber( $srcIdCardNum );
        }
    }

    if ( defined( 'FUNCTION_DEBUG' ) || !function_exists( 'GetIdCard18To15' ) ) {
        /**
         * 将18位身份证号码转为15位
         *
         * @param $src string 18位身份证号码
         * @return string 15位身份证号码
         */
        function GetIdCard18To15 ( $srcIdCardNum = 0 )
        {
            if ( strlen( $srcIdCardNum ) != 18 ) {
                return FALSE;
            }

            return substr( $srcIdCardNum, 0, 6 ) . substr( $srcIdCardNum, 8, 9 );
        }
    }

    if ( defined( 'FUNCTION_DEBUG' ) || !function_exists( 'CheckIdCard18' ) ) {
        /**
         * 验证18位身份证号码最后一位校验是否正确
         *
         * @param $src string 原始数据
         * @return bool 返回TRUE表示验证通过，FALSE表示验证未通过
         */
        function CheckIdCardNumber ( $srcIdCardNum = 0 )
        {
            if ( strlen( $srcIdCardNum ) == 15 ) {
                $srcIdCardNum = GetIdCard15To18( $srcIdCardNum );
            }
            if ( strlen( $srcIdCardNum ) != 18 ) {
                return FALSE;
            }
            $baseIdCardNum = substr( $srcIdCardNum, 0, 17 ); //获取前17位号码
            $lastVerifyNum = strtoupper( substr( $srcIdCardNum, 17, 1 ) ); //获取第18位校验码
            if ( GetIdCardLastVerifyNumber( $baseIdCardNum ) != $lastVerifyNum ) {
                return FALSE;
            } else {
                return TRUE;
            }
        }
    }
    // ------------------------------------------------------------------------

}   //END if
